package com.yhb.base.string;

import com.yhb.base.annotation._2_annotation;

/**
 * Created by yanghongbo on 2020/2/25.
 */
public class _1_String {

    public static void main(String[] arg) {
        String str1 = "abc";
        String str2 = "abc";
        System.out.println(str1 == str2);
        System.out.println(str1.equals(str2));
        System.out.println("----------------------");

        String str3 = new String("abc");
        String str4 = new String("abc");
        System.out.println(str3 == str4);
        System.out.println(str3.equals(str4));

        //str1常量池，str3堆对象
        System.out.println(str1 == str3);
        //最终结果就是返回一个指向常量池字符串的引用
        System.out.println(str1 == str3.intern());

        testString();
    }
    @_2_annotation(value = "testString")
    private static void testString() {
        String hello = "Hello";
        String hello2 = new String("Hello");
        String lo = "lo";
        //false. ==比较的是引用.hello是一个字符串常量表达式，并实现为调用interned，以共享不同的示例（string pool）
        //hello2是一个对象，指向的是堆上的一个地址
        System.out.println(hello == hello2);            //false
        //true. equals比较的是两个对象的值
        System.out.println(hello.equals(hello2));       //true
        //true. intern()会检查当前字符串池是否包含这个字符串。包含则返回池中的字符串，否则将字符串对象添加到池中，并返回该字符串对象的引用
        //（最终结果就是返回一个指向常量池字符串的引用）
        System.out.println(hello == hello2.intern());   //true
        //true. 两个都是常量表达式(编译时确定的)，都是指向字符串池的引用
        System.out.println(hello == "Hello");           //true
        //true. 不同类下的两个常量表达式，依然是指向同一个字符串池的引用
        System.out.println(Other.hello == hello);       //true
        //true. 不同包下的两个常量表达式，依然是指向同一个字符串池的引用
        //System.out.println(com.example.base.string.other.Other.hello == hello);     //true
        //true. 两个都是常量表达式，都是指向字符串池的引用
        System.out.println(hello == ("Hel" + "lo"));    //true
        //false.  后者不是常量表达式，是运行时通过串联计算的字符串（lo是一个对象，不是常亮"xxx"），会新建对象
        System.out.println(hello == ("Hel" + lo));      //false
        //true. 将新对象intern()会返回指向字符串池的引用
        System.out.println(hello == ("Hel" + lo).intern());     //true
    }
}
class Other {
    static String hello = "Hello";
}

